// float4x4 -> D3DXMATRIX
// float4
// float3
// float2
// float
// int

uniform extern float4x4 gWVP;
uniform extern float gTime;
uniform extern texture gTex;

sampler TexS = sampler_state
{
	Texture = <gTex>;
	MinFilter = Anisotropic;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	MaxAnisotropy = 8;
	AddressU = WRAP;
	AddressV = WRAP;
};

uniform int NB_WAVE = 2;

// Amplitude
static float a[2] = { 2.0f, 3.8f };

// Angular wave number
static float k[2] = { 0.04f, 0.16f };

// Angular frequency
static float w[2] = { 0.4f, 0.7f };

// Phase shift
static float p[2] = { 1.0f, 3.0f };

struct OutputVS
{
			   // Semantique
	float4 posH: POSITION0;
};

struct OutputVSColor
{
			   // Semantique
	float4 posH: POSITION0;
	float4 col: COLOR0;
};

struct OutputVSPNT
{
	float4 posH: POSITION0;
	float4 diffuse: COLOR0;
	float2 tex0: TEXCOORD0;
};

float SumOfRadialSineWave(float x, float z);

// Fonction VertexShaders
OutputVS TransformVS(float3 posL: POSITION0)
{
	OutputVS outVS = (OutputVS)0;
	outVS.posH = mul(float4(posL, 1.0f), gWVP);
	return outVS;
}

OutputVSColor TransformVSColor(float3 posL: POSITION0, float4 col: COLOR0)
{
	OutputVSColor outVS = (OutputVSColor)0;
	outVS.posH = mul(float4(posL, 1.0f), gWVP);
	outVS.col = col;
	return outVS;
}

OutputVSColor TransformVSColorWave(float3 posL: POSITION0, float4 col : COLOR0)
{
	OutputVSColor outVS = (OutputVSColor)0;
	posL.y += SumOfRadialSineWave(posL.x, posL.z);
	outVS.posH = mul(float4(posL, 1.0f), gWVP);

	if (posL.y < -2.2f)
		outVS.col = float4(1.0f, 1.0f, 1.0f, 1.0f);
	else
		outVS.col = col;

	return outVS;
}

OutputVSColor TransformVSWireColor(float3 posL: POSITION0, float4 col : COLOR0)
{
	OutputVSColor outVS = (OutputVSColor)0;
	posL.y -= 0.1f;
	outVS.posH = mul(float4(posL, 1.0f), gWVP);
	outVS.col = col;
	return outVS;
}

OutputVSColor TransformVSWireColorWave(float3 posL: POSITION0, float4 col : COLOR0)
{
	OutputVSColor outVS = (OutputVSColor)0;
	posL.y += SumOfRadialSineWave(posL.x, posL.z) - 0.1f;
	outVS.posH = mul(float4(posL, 1.0f), gWVP);
	outVS.col = col;
	return outVS;
}

OutputVSPNT TransformVSPNT(float3 posL : POSITION0, float3 normalL : NORMAL0, float2 tex0 : TEXCOORD0)
{
	OutputVSPNT outVS = (OutputVSPNT)0;
	outVS.posH = mul(float4(posL, 1.0f), gWVP);
	outVS.diffuse = float4(1.0f, 1.0f, 1.0f, 1.0f);
	outVS.tex0 = tex0;
	return outVS;
}

float4 TransformPSPNT(float4 c: COLOR0, float2 tex0: TEXCOORD0): COLOR0
{
	float3 texColor = tex2D(TexS, tex0).rgb;
	float3 diffuse = c.rgb * texColor;
	return float4(diffuse, c.a);
}

// Fonction PixelShaders
float4 TransformPS(OutputVS inVS): COLOR0
{
	return float4(0.5f, 0.5f, 0.0f, 1.0f);
}

float4 TransformPSColor(OutputVSColor inVS): COLOR0
{
	return inVS.col;
}

float4 WireColor(OutputVS inVS) : COLOR0
{
	return float4(0.0f, 0.0f, 0.0f, 1.0f);
}

float SumOfRadialSineWave(float x, float z)
{
	float d = sqrt(x*x + z*z);

	float sum = 0.0f;
	for (int i = 0; i < NB_WAVE; i++)
	{
		sum += a[i] * sin(k[i] * d - gTime*w[i] + p[i]);
	}
	return sum;
}

technique TransformTech
{
	pass P0
	{
		vertexShader = compile vs_3_0 TransformVS();
		pixelShader = compile ps_3_0 TransformPS();
		FillMode = Solid;
	}
	pass P1
	{
		pixelShader = compile ps_3_0 WireColor();
		FillMode = WireFrame;
	}
}

technique TransformColorTech
{
	pass P0
	{
		vertexShader = compile vs_3_0 TransformVSColor();
		pixelShader = compile ps_3_0 TransformPSColor();
		FillMode = Solid;
	}
	pass P1
	{
		vertexShader = compile vs_3_0 TransformVSWireColor();
		pixelShader = compile ps_3_0 WireColor();
		FillMode = WireFrame;
	}
}

technique TransformColorWaveTech
{
	pass P0
	{
		vertexShader = compile vs_3_0 TransformVSColorWave();
		pixelShader = compile ps_3_0 TransformPSColor();
		FillMode = Solid;
	}
	pass P1
	{
		vertexShader = compile vs_3_0 TransformVSWireColorWave();
		pixelShader = compile ps_3_0 WireColor();
		FillMode = WireFrame;
	}
}

technique TransformPNTTech
{
	pass P0
	{
		vertexShader = compile vs_2_0 TransformVSPNT();
		pixelShader = compile ps_2_0 TransformPSPNT();
		//FillMode = Solid;
	}
	//pass P1
	//{
	//	pixelShader = compile ps_3_0 WireColor();
	//	FillMode = WireFrame;
	//}
}